package biz.datalk.industrialland.admin.modules.online.config.util;

import biz.datalk.industrialland.admin.modules.online.config.hook.IDynfromHook;
import biz.datalk.industrialland.admin.modules.online.config.hook.impl.DefaultDynfromHookImpl;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ConcurrentHashMap;

/**
 *
 *
 * @author tarofang@163.com
 * @date 2019-12-30
 *
 */
public class HookUtil {
    private static final Logger log = LoggerFactory.getLogger(HookUtil.class);

    /** 用户存储 hook 实例 */
    private static final ConcurrentHashMap<String, IDynfromHook> HOOK_MAP = new ConcurrentHashMap<>();

    /** 默认实例 */
    private static final IDynfromHook DEFAULT_HOOK = new DefaultDynfromHookImpl();

    /** HOOK_MAP 加入 默认实例 */
    private HookUtil() {
        HookUtil.HOOK_MAP.put(DefaultDynfromHookImpl.class.getName(), DEFAULT_HOOK);
    }

    /**
     * 根据类的完全限定名获取实例
     *
     * @author tarofang@163.com
     * @date 2019年12月30日
     *
     * @param classFullyName 类的完全限定名
     * @param null2Def 不存在时，是否返回默认值 true-返回默认值 否则不返回默认值
     * @return 类的实例
     */
    public static IDynfromHook newInstance(String classFullyName, boolean null2Def) {
        if (StringUtils.isBlank(classFullyName)) {
            return null2Def ? DEFAULT_HOOK : null;
        }
        IDynfromHook hook = HOOK_MAP.get(classFullyName.trim());
        if (hook != null) {
            return hook;
        }
        try {
            hook = (IDynfromHook) Thread.currentThread().getContextClassLoader().loadClass(classFullyName.trim()).newInstance();
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException ex) {
            log.warn(ex.getMessage(), ex);
        }

        if (hook != null) {
            HOOK_MAP.put(classFullyName, hook);
            return hook;
        }

        return null2Def ? DEFAULT_HOOK : null;
    }

    /**
     * 根据类的完全限定名获取实例
     *
     * @author tarofang@163.com
     * @date 2019年12月30日
     *
     * @param classFullyName 类的完全限定名
     * @return 类的实例
     *
     * @see HookUtil#newInstance(String, boolean)
     */
    public static IDynfromHook newInstance(String classFullyName) {
        return newInstance(classFullyName, Boolean.TRUE);
    }

    public static boolean isExistsImplClass(String classFullyName) {
        try {
            IDynfromHook hook = (IDynfromHook) Thread.currentThread().getContextClassLoader().loadClass(StringUtils.trimToEmpty(classFullyName)).newInstance();
            return hook != null;
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException ex) {
            return false;
        }
    }

}
